
#ifndef __RSP__FCB__HEADER_FILE__
#define __RSP__FCB__HEADER_FILE__

////////////////////////////////////////////////////////////////////////////////
///Buffer holding a per-frame object commands
struct frame_command_buffer : dynarray<uchar>
{
    template<class T>
    void set( const T& p )              { *(T*)add(sizeof(T)) = p; }

    template<class T>
    void setn( const T* p, uints n )    { ::memcpy( add(n*sizeof(T)), p, n*sizeof(T) ); }

    void setb( const void* p, uints n ) { ::memcpy( add(n), p, n ); }

    void sets( const char* s, uints n ) { uchar* p=add(1+n);  *p=(uchar)n;  ::memcpy( p+1, s, n ); }
};

struct frame_command_reader
{
    const uchar* ptr;

    explicit frame_command_reader( const uchar* data ) : ptr(data) { }
    explicit frame_command_reader( const frame_command_buffer& fcb ) : ptr(fcb.ptr()) { }

    template<class T>
    void get( T& p )                    { p = *(const T*)ptr;  ptr += sizeof(T); }

    template<class T>
    void getn( T* p, uints n )          { ::memcpy( p, ptr, n*sizeof(T) );  ptr += n*sizeof(T); }

    void getb( void* p, uints n )       { ::memcpy( p, ptr, n );  ptr += n; }

    token gets()                        { token t( (const char*)ptr+1, *ptr );  ptr += 1+*ptr;  return t; }
};


template<class T>
inline frame_command_buffer& operator << (frame_command_buffer& fcb, const T& v)
{   fcb.set(v);  return fcb; }

template<class T>
inline frame_command_reader& operator >> (frame_command_reader& fcr, T& v)
{   fcr.get(v);  return fcr; }


inline frame_command_buffer& operator << (frame_command_buffer& fcb, const token& v)
{   fcb.sets( v.ptr(), v.len() );  return fcb; }

inline frame_command_buffer& operator << (frame_command_buffer& fcb, const charstr& v)
{   fcb.sets( v.ptr(), v.len() );  return fcb; }

inline frame_command_reader& operator >> (frame_command_reader& fcr, token& v)
{   v = fcr.gets();  return fcr; }

inline frame_command_reader& operator >> (frame_command_reader& fcr, charstr& v)
{   v = fcr.gets();  return fcr; }



#endif //__RSP__FCB__HEADER_FILE__

